import React, {useEffect, useState, useCallback, forwardRef, useMemo} from 'react';
import {useSelector} from 'react-redux'
import {Table} from 'antd';
import apis from "@/axios/apis.ts"

interface Props<T> {
    columns: Table.ColumnsType<T>;
    rowKey?: string | ((record: T) => string);
    tableProps?: Omit<Table<T>, 'dataSource' | 'columns' | 'pagination' | 'loading' | 'rowKey'>;
    paginationProps?: Omit<PaginationProps, 'total' | 'current' | 'pageSize' | 'onChange'>;
    searchForm: object,
    multiple?: Boolean;
    multipleChange?: Function
}


interface User {
    key: string;
    name: string;
    age: number;
    address: string;
}

const PageTable = forwardRef(({
                                  columns,
                                  rowKey = 'id',
                                  reqestUrl = '',
                                  searchForm = {},
                                  multiple,
                                  multipleChange,
                                  setCurrentPageField = true,
                                  initPageNumber = 1,
                                  pageNumKey = 'pageNum',
                                  pageSizeKey = 'pageSize',
                                  getData
                              }: Props, ref) => {
    const {formAdvancedSearch} = useSelector((state: any) => state.userSlice)
    const [dataSource, setDataSource] = useState<User[]>([]);
    const [pageParam, setPageParams] = useState({
        pageNum: initPageNumber,
        pageSize: 10,
    })
    const [totalPages, setTotalPages] = useState(0)
    const [tableHeight, setTableHeight] = useState(500)
    const delColumns = useMemo(() => {
        return columns.reduce((res, cur) => {
            if (!cur.minWidth) {
                cur.minWidth = 100
            }
            res.push(cur)
            return res
        }, [])
    }, [columns])
    // 表格多选的数据
    const [selectedRowKeys, setSelectedRowKeys] = useState<Array<string>>([]);
    const [selectedRow, setSelectedRows] = useState<Array<object>>([]);
    const fetchData = useCallback((pageObj = {}, values = null) => {
        let params = {
            [pageNumKey]: pageObj.pageNum || pageParam.pageNum,
            [pageSizeKey]: pageObj.pageSize || pageParam.pageSize,
        }
        if (values) {
            params = {...params, ...values}
        } else {
            params = {...params, ...searchForm}
        }
        apis[reqestUrl](params).then(res => {
            if (+res.code === 200) {
                if (getData) {
                    getData(res.data.records)
                }
                setDataSource(res.data.records)
                setPageParams({
                    pageNum: setCurrentPageField ? res.data.current : (pageObj.pageNum || pageParam.pageNum),
                    pageSize: res.data.size,
                })
                setTotalPages(res.data.total)
            }
        })
    }, []);
    const rowSelection = {
        type: 'checkbox', // 指定多选模式
        selectedRowKeys,
        onChange: (keys: Array<string>, selectedRows: Array<object>) => {
            setSelectedRowKeys(keys);
            setSelectedRows(selectedRows);
        },
    }
    const onChange = (pageNum: number, pageSize: number) => {
        const pageObj = {
            pageNum,
            pageSize,
            total: totalPages,
        }
        setPageParams(pageObj)
        fetchData(pageObj)
    };
    useEffect(() => {
        if (reqestUrl) {
            fetchData(pageParam);
        }
        window.addEventListener('resize', handleResize);
        // 组件卸载时移除事件监听（防止内存泄漏）
        return () => {
            window.removeEventListener('resize', handleResize);
        };
    }, []);
    useEffect(() => {
        getTableHeight()
    }, [formAdvancedSearch]);
    // 监听多选数组传给父组件
    useEffect(() => {
        if (multipleChange) {
            multipleChange(selectedRowKeys, selectedRow)
        }
    }, [selectedRowKeys])
    // 当组件挂载后，将这个组件的实例传递给父组件
    React.useImperativeHandle(ref, () => ({
        // 请求列表
        fetchData,
        // 清空多选
        clearSelection: () => {
            setSelectedRowKeys([])
            setSelectedRows([])
        }
    }));
    const handleResize = useCallback(
        lodash.throttle(() => {
            getTableHeight()
        }, 300),
        []
    );
    const getTableHeight = () => {
        const pageContent = document.getElementsByClassName('page-content')[0] || null // page-content
        const pageForm = document.getElementsByClassName('search-forms')[0] || null // 搜素表单
        const pageAction = document.getElementsByClassName('page-action-bar')[0] || null // 操作按钮
        const pagePagination = 46 // 分页器高度
        let marginHeight = 0 // 上下margin
        if (pageContent) {
            marginHeight = marginHeight + 40
        }
        if (pageForm) {
            marginHeight = marginHeight + 24
        }
        if (pageAction) {
            marginHeight = marginHeight + 40
        }
        marginHeight = marginHeight + 46 // table的margin
        let height = pageContent.clientHeight - pagePagination - marginHeight
        if (pageForm) {
            height = height - pageForm.clientHeight
        }
        if (pageAction) {
            height = height - pageAction.clientHeight
        }
        setTableHeight(height)
    }

    return (
        <div className="table-pagination-container">
            <Table
                dataSource={dataSource}
                columns={delColumns}
                rowKey={rowKey}
                size="middle"
                bordered={true}
                pagination={{
                    position: ['bottomRight'],
                    current: pageParam.pageNum,
                    pageSize: pageParam.pageSize,
                    total: totalPages,
                    onChange: onChange,
                    showTotal: (totalPages) => `共${totalPages}条`
                }}
                style={{width: '100%'}}
                rowSelection={multiple ? rowSelection : null}
                scroll={{y: tableHeight}}
            />
        </div>
    )
})

export default PageTable;